import React, { useState, useEffect, useMemo, useCallback } from 'react';
import {
  Form,
  Input,
  Select,
  DatePicker,
  TimePicker,
  InputNumber,
  Switch,
  Checkbox,
  Radio,
  Cascader,
  Slider,
  Rate,
  Button,
  Row,
  Col,
  Space,
} from 'antd';
import { DownOutlined, UpOutlined, SearchOutlined, ReloadOutlined } from '@ant-design/icons';

const { Option } = Select;
const { TextArea } = Input;

// 组件类型映射表
const componentMap = {
  text: Input,
  input: Input,
  textarea: TextArea,
  select: Select,
  date: DatePicker,
  datetime: DatePicker,
  time: TimePicker,
  number: InputNumber,
  switch: Switch,
  checkbox: Checkbox,
  radio: Radio.Group,
  cascader: Cascader,
  slider: Slider,
  rate: Rate,
};

const DynamicForm = (props) => {
  const {
    fields = [],
    initialValues = {},
    layout = 'horizontal',
    align = 'right', // 按钮组整体对齐方式
    gutter = 24,
    defaultColSpan = 6,
    maxVisible = 6,
    // 按钮配置（默认包含搜索、重置）
    actionButtons = [
      { text: '搜索', type: 'primary', htmlType: 'submit', icon: <SearchOutlined /> },
      { text: '重置', icon: <ReloadOutlined /> }
    ],
    expandText = '展开',
    collapseText = '收起',
    className = '',
    labelWidth = 100,
    required = false,
    onFinish,
    onFinishFailed,
    onReset,
    onChange,
    onExpandChange,
  } = props;

  // 表单实例与状态
  const [form] = Form.useForm();
  const [expand, setExpand] = useState(false);

  // 初始化表单数据
  useEffect(() => {
    const initValues = {};
    fields.forEach(field => {
      initValues[field.key] = initialValues[field.key] ?? field.defaultValue ?? '';
    });
    form.setFieldsValue(initValues);
  }, [initialValues, fields, form]);

  // 是否需要折叠
  const hasCollapse = useMemo(() => {
    return fields.length > maxVisible && maxVisible > 0;
  }, [fields.length, maxVisible]);

  // 可见字段
  const visibleFields = useMemo(() => {
    if (!hasCollapse) return fields;
    return expand ? fields : fields.slice(0, maxVisible);
  }, [fields, expand, hasCollapse, maxVisible]);

  // 获取组件与属性（复用之前的逻辑）
  const getComponent = useCallback((type) => componentMap[type] || Input, []);
  
  const getComponentProps = useCallback((field) => {
    const baseProps = {
      placeholder: field.placeholder || `请输入${field.label}`,
      disabled: field.disabled || false,
      style: { width: field.width || '100%', ...field.style },
      ...field.props,
    };
    if (field.type === 'datetime') return { ...baseProps, showTime: true, format: 'YYYY-MM-DD HH:mm:ss' };
    if (field.type === 'number') return { ...baseProps, min: field.min, max: field.max, step: field.step };
    return baseProps;
  }, []);

  // 字段规则与布局（复用之前的逻辑）
  const getFieldRules = useCallback((field) => {
    const isRequired = field.required ?? required;
    const rules = isRequired ? [{ required: true, message: `请输入${field.label}` }] : [];
    return field.rules ? [...rules, ...field.rules] : rules;
  }, [required]);

  const getLabelCol = useCallback((field) => field.labelCol || {
    xs: { span: 24 },
    sm: { span: layout === 'horizontal' ? 6 : 24 },
    style: { width: labelWidth, flex: `0 0 ${labelWidth}px` },
  }, [layout, labelWidth]);

  const getWrapperCol = useCallback((field) => field.wrapperCol || {
    xs: { span: 24 },
    sm: { span: layout === 'horizontal' ? 18 : 24 },
  }, [layout]);

  // 切换折叠状态
  const toggleExpand = () => {
    setExpand(!expand);
    onExpandChange?.(!expand);
  };

  // 处理字段变化与重置
  const handleFieldChange = (key, value) => onChange?.({ key, value, formData: form.getFieldsValue() });
  const handleReset = () => { form.resetFields(); onReset?.(); };

  // 渲染表单项
  const renderFormItem = (field) => {
    const Component = getComponent(field.type);
    const props = getComponentProps(field);
    const { key, label, options = [] } = field;

    const renderOptions = () => {
      if (field.type === 'select') return options.map(opt => (
        <Option key={opt.value} value={opt.value}>{opt.label}</Option>
      ));
      if (field.type === 'radio') return options.map(opt => (
        <Radio key={opt.value} value={opt.value}>{opt.label}</Radio>
      ));
      return null;
    };

    return (
      <Col
        key={key}
        span={field.span || defaultColSpan}
        offset={field.offset || 0}
        style={field.containerStyle}
        className="form-item-col"
      >
        <Form.Item
          name={key}
          label={label}
          rules={getFieldRules(field)}
          labelCol={getLabelCol(field)}
          wrapperCol={getWrapperCol(field)}
          style={{height:32}}
        >
          <Component {...props} onChange={(v) => handleFieldChange(key, v)}>
            {renderOptions()}
          </Component>
        </Form.Item>
      </Col>
    );
  };

  // 渲染按钮组（含展开/收起按钮）
  const renderActionButtons = () => (
    <Space>
      {/* 搜索、重置等主按钮 */}
      {actionButtons.map((btn, idx) => (
        <Button
          key={idx}
          type={btn.type || 'default'}
          htmlType={btn.htmlType || 'button'}
          icon={btn.icon}
          onClick={btn.handler || (btn.text === '重置' ? handleReset : undefined)}
          className="action-btn"
        >
          {btn.text}
        </Button>
      ))}

      {/* 展开/收起按钮（与主按钮同组） */}
      {hasCollapse && (
        <Button
          type="text"
          onClick={toggleExpand}
          className="collapse-btn"
          style={{ marginLeft: 8 }}
        >
          {expand ? <UpOutlined style={{ marginRight: 4 }} /> : <DownOutlined style={{ marginRight: 4 }} />}
          {expand ? collapseText : expandText}
        </Button>
      )}
    </Space>
  );

  return (
    <Form
      form={form}
      layout={layout}
      className={`dynamic-form ${className}`}
      onFinish={onFinish}
      onFinishFailed={onFinishFailed}
      style={{ width: '100%',}}
    >
      {/* 表单项区域 */}
      <Row gutter={gutter}>
        {visibleFields.map(field => renderFormItem(field))}
      </Row>

      {/* 按钮区域（搜索、重置、展开/收起在同一行） */}
      <Row style={{ marginTop: 16 }}>
        <Col span={24} style={{ textAlign: align }}>
          {renderActionButtons()}
        </Col>
      </Row>
    </Form>
  );
};

export default DynamicForm;